package com.silver.weibo.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.silver.weibo.dao.CityMapper;
import com.silver.weibo.dao.LabelMapper;
import com.silver.weibo.dao.ProvinceMapper;
import com.silver.weibo.entity.*;
import com.silver.weibo.entity.dto.BlogListDTO;
import com.silver.weibo.entity.dto.MyAttentionDTO;
import com.silver.weibo.entity.vo.*;
import com.silver.weibo.server.*;
import com.silver.weibo.utils.MyContextUtil;
import com.silver.weibo.utils.PageUtil;
import com.silver.weibo.utils.UploadImage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.util.StringUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Controller
@RequestMapping("/user")
public class UserController {

    private final UploadImage uploadImage;
    private final UserService userService;
    private final ProvinceMapper provinceMapper;
    private final CityMapper cityMapper;
    private final LabelMapper labelMapper;
    private final BlogService blogService;
    private final LikeService likeService;
    private final CollectService collectService;
    private final AttentionService attentionService;
    //private static final Logger logger = LogManager.getLogger(UserController.class);

    @Autowired
    public UserController(UploadImage uploadImage, UserService userService, ProvinceMapper provinceMapper, CityMapper cityMapper,
                          LabelMapper labelMapper, BlogService blogService, LikeService likeService,
                          CollectService collectService, AttentionService attentionService) {
        this.uploadImage = uploadImage;
        this.userService = userService;
        this.provinceMapper = provinceMapper;
        this.cityMapper = cityMapper;
        this.labelMapper = labelMapper;
        this.blogService = blogService;
        this.likeService = likeService;
        this.collectService = collectService;
        this.attentionService = attentionService;
    }

    // 写博客
    @GetMapping("/modifyBlog")
    public String modifyBlog(Model model) {
        List<Labels> labels = labelMapper.selectList(null);

        // 查询hot排行榜
        getBlogRange(model);

        model.addAttribute("labels", labels)
                .addAttribute("pageName", "add");

        return "modifyBlog";
    }

    // 进入个人新信息页面
    @GetMapping("/userinfo")
    public String userinfo(Model model) {

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.eq("id", userVO.getUser().id);
        Users one = userService.getOne(wrapper);
        model.addAttribute("UserInfo", one);

        List<Province> provinces = provinceMapper.selectList(null);
        model.addAttribute("provinces", provinces);

        List<City> cities = cityMapper.selectList(new QueryWrapper<City>().eq("provinceid", one.getUserProvince()));
        model.addAttribute("cities", cities);

        // 查询hot排行榜
        getBlogRange(model);

        return "userInfo";
    }

    // 异步交互加载省份信息
    @GetMapping("/getProvince")
    @ResponseBody
    public String getProvince() {
        return JSON.toJSONString(provinceMapper.selectList(null));
    }

    // 异步交互加载该省份的信息
    @GetMapping("/getCity")
    @ResponseBody
    public String getCity(@RequestParam("provinceid") int id) {
        return JSON.toJSONString(cityMapper.selectList(new QueryWrapper<City>().eq("provinceid", id)));
    }

    // 修改个人信息
    @PostMapping("/modifyInfo")
    public String modifyInfo(Users user, @RequestPart("userImageSrc") MultipartFile userimage) throws IOException {

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        UpdateWrapper<Users> upWar = new UpdateWrapper<>();
        upWar.eq("user_loginname", user.getUserLoginname())
                .set("user_nickname", user.getUserNickname().trim())
                .set("user_province", user.getUserProvince())
                .set("user_city", user.getUserCity())
                .set("user_sex", user.getUserSex())
                .set("user_signature", user.getUserSignature().trim())
                .set("user_birthday", user.getUserBirthday());

        String s = uploadImage.upload(userimage);

        if (StringUtils.isEmpty(s)) {
            upWar.set("user_image", userVO.getUser().getUserImage());
        } else {
            upWar.set("user_image", s);
        }

        userService.update(upWar);

        return "redirect:/index/loginSucc";
    }

    // 用户关注功能
    @GetMapping("/attention")
    @ResponseBody
    public Map<String, String> attention(@RequestParam("bloggerId") Integer bloggerId) {

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        Attention attention = new Attention();
        HashMap<String, String> map = new HashMap<>();

        attention.setUserId(userVO.getUser().id);
        attention.setBloggerId(bloggerId);

        // 判断是否是第一次关注该博主
        Attention one = attentionService.selectOneByAttention(attention);

        boolean b;
        if (one != null) {

            b = attentionService.saveAgain(attention);

        } else {

            b = attentionService.save(attention);

        }
        if (b) {
            map.put("msg", "success");
        } else {
            map.put("msg", "error");
        }
        return map;

    }

    // 用户在博客详情页取消关注功能
    @GetMapping("/unAttention")
    @ResponseBody
    public Map<String, String> unAttention(@RequestParam("bloggerId") Integer bloggerId) {

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        QueryWrapper<Attention> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userVO.getUser().id)
                .eq("blogger_id", bloggerId);

        boolean b = attentionService.remove(wrapper);

        HashMap<String, String> map = new HashMap<>();
        if (b) {
            map.put("msg", "success");
        } else {
            map.put("msg", "error");
        }

        return map;
    }

    // 用户在我的关注列表取消关注功能
    @GetMapping("/unAttention2")
    public String unAttention2(@RequestParam("bloggerId") Integer bloggerId) {

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        QueryWrapper<Attention> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userVO.getUser().id)
                .eq("blogger_id", bloggerId);

        attentionService.remove(wrapper);

        return "redirect:/user/attentionList?pageNo=1";
    }

    // 进入详情页的时候偶的一些检查和判断
    @GetMapping("/check")
    @ResponseBody
    public Map<String, String> checkAttention(@RequestParam("bloggerId") Integer bloggerId,
                                              @RequestParam("blogId") Integer blogId) {

        HashMap<String, String> map = new HashMap<>();

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        // 判断该博客是否点过赞
        QueryWrapper<Likes> wrapper = new QueryWrapper<>();
        wrapper.eq("blog_id", blogId)
                .eq("user_id", userVO.getUser().id);
        Likes likes = likeService.getOne(wrapper);

        if (likes == null || likes.getDeleted() == 1) {
            map.put("likes", "no");
        } else {
            map.put("likes", "yes");
        }

        // 判断是否收藏过该博客
        QueryWrapper<Collect> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("blog_id", blogId)
                .eq("user_id", userVO.getUser().id);
        Collect collect = collectService.getOne(wrapper1);

        if (collect == null || collect.getDeleted() == 1) {
            map.put("collect", "no");
        } else {
            map.put("collect", "yes");
        }


        if (userVO.getUser().id.equals(bloggerId)) {
            map.put("msg", "same");
            return map;
        }

        // 查询用户是否有关注该博主
        Attention attention = new Attention(null, userVO.getUser().id, bloggerId, 0);

        Attention one = attentionService.selectOneByAttention(attention);

        if (one != null) {
            map.put("msg", "followed");
        } else {
            map.put("msg", "notFollowed");
        }

        return map;
    }

    // 进入我的关注列表
    @GetMapping("/attentionList")
    public String attention(MyAttentionDTO myAttentionDTO, Model model) {

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        myAttentionDTO.setUserId(userVO.getUser().id);
        int pageNo = myAttentionDTO.getPageNo();
        myAttentionDTO.setPageNo(pageNo * 10 - 10);

        List<MyAttentionVO> list = attentionService.selectMyAttentionByUserId(myAttentionDTO);

        PageUtil pageUtil = new PageUtil(list.size(), myAttentionDTO.getPageNo(), 10);
        List<Integer> pageList = pageUtil.countPreAndSufNo();

        // 查询hot排行榜
        getBlogRange(model);

        model.addAttribute("pageName", "attention")
                .addAttribute("bloggerNameKey", myAttentionDTO.getBloggerNameKey())
                .addAttribute("attentionList", list)
                .addAttribute("pageNumList", pageList)
                .addAttribute("pageNo", pageNo)
                .addAttribute("totalPage", pageUtil.getTotalPageNo());

        return "attention";
    }

    // 进入博主详情页的准备工作
    @GetMapping("/toViewBlogger/{userId}")
    public String toViewBlogger(@PathVariable("userId") Integer userId, Model model) {

        // 查询出blogger的基本信息
        ViewBloggerVO viewBloggerVO = userService.selectBloggerById(userId);

        // 分页查询该博主的博客
        Page<BlogDetailVO> page = new Page<>(1, 6);
        BlogListDTO blogListDTO = new BlogListDTO(userId, null, null);
        blogService.selectAllByActive(page, blogListDTO);

        // 查询博主的粉丝数目
        QueryWrapper<Attention> wrapper = new QueryWrapper<>();
        wrapper.eq("blogger_id", userId);
        int count = attentionService.count(wrapper);

        // 查询博主所有博客点赞的总数
        QueryWrapper<Blogs> wrapper2 = new QueryWrapper<>();
        wrapper2.select("IFNULL(sum(likes),0) as likes").eq("user_id", userId);
        // 把查询到的 字段 与 值 存到一个map中
        Map<String, Object> map = blogService.getMap(wrapper2);
        // sum()函数返回值是 BigDecimal
        BigDecimal bdc = (BigDecimal) map.get("likes");
        // 把 BigDecimal转成Integer的方法
        Integer likes = Integer.parseInt(bdc.toString());

        // 把博客数，粉丝数，点赞数 存到VO类中
        viewBloggerVO.setBlogCount((int) page.getTotal());
        viewBloggerVO.setFans(count);
        viewBloggerVO.setLikes(likes);

        model.addAttribute("blogger", viewBloggerVO)
                .addAttribute("blogs", page.getRecords());

        // 查询hot排行榜
        getBlogRange(model);

        return "viewblogger";
    }

    // 博客详情页的点赞功能
    @GetMapping("/like/{id}")
    @ResponseBody
    public Map<String, String> blogLike(@PathVariable("id") Integer blogId) {

        HashMap<String, String> restMap = new HashMap<>();

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        // 检查是否第一次点击like
        Likes one = likeService.selectAllByUserIdAndBlogId(new Likes(null, userVO.getUser().id, blogId, null));

        if (one != null && one.getDeleted() == 0) {
            restMap.put("msg", "success");
            return restMap;
        }

        boolean b;
        if (one != null && one.getDeleted() == 1) {
            one.setDeleted(0);
            b = likeService.updateDel(one);

        } else {
            b = likeService.save(new Likes(null, userVO.getUser().id, blogId, 0));
        }

         // 更新likes信息
        updateLikes(blogId);

        if (b) {
            restMap.put("msg", "success");
        } else {
            restMap.put("msg", "error");
        }

        return restMap;
    }

    // 博客详情页的取消点赞功能
    @GetMapping("/unlike/{id}")
    @ResponseBody
    public Map<String, String> unLike(@PathVariable("id") Integer blogId) {

        HashMap<String, String> restMap = new HashMap<>();

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        QueryWrapper<Likes> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userVO.getUser().id)
                .eq("blog_id", blogId);

        boolean b = likeService.remove(wrapper);

        // 更新likes
        updateLikes(blogId);

        if (b) {
            restMap.put("msg", "success");
        } else {
            restMap.put("msg", "error");
        }

        return restMap;
    }

    // 博客详情页的收藏功能
    @GetMapping("/collect/{blogId}")
    @ResponseBody
    public Map<String, String> collect(@PathVariable("blogId") Integer blogId) {

        HashMap<String, String> map = new HashMap<>();

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        Collect collect = new Collect(null, userVO.getUser().id, blogId, null, 0);

        Collect one = collectService.selectByUserIdAndBlogID(collect);

        if (one != null && one.getDeleted() == 0) {
            map.put("collect", "success");
            return map;
        }

        boolean b;
        if (one != null) {
            one.setDeleted(0);
            b = collectService.updateByCollect(one);
        } else {

            b = collectService.save(collect);
        }

        if (b) {

            map.put("collect", "success");

        } else {
            map.put("collect", "error");
        }

        return map;
    }

    // 博客详情页的取消收藏功能
    @GetMapping("/unCollect/{blogId}")
    @ResponseBody
    public Map<String, String> unCollect(@PathVariable("blogId") Integer blogId) {

        HashMap<String, String> map = new HashMap<>();

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        QueryWrapper<Collect> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userVO.getUser().id)
                .eq("blog_id", blogId);

        boolean b = collectService.remove(wrapper);

        if (b) {
            map.put("collect", "success");
        } else {
            map.put("collect", "error");
        }

        return map;
    }

    // 博客详情页的取消收藏功能
    @GetMapping("/unCollect2/{blogId}")
    public String unCollect2(@PathVariable("blogId") Integer blogId) {

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        QueryWrapper<Collect> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userVO.getUser().id)
                .eq("blog_id", blogId);

        collectService.remove(wrapper);
        return "redirect:/user/myCollectList?pageNo=1";
    }

    // 进入我的收藏夹
    @GetMapping("/myCollectList")
    public String myCollectList(@RequestParam("pageNo") Integer pageNo, Model model) {

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        Page<CollectVO> page = new Page<>(pageNo, 10);

        collectService.selectMyCollectDetail(page, userVO.getUser().id);

        // 设置分页与计算分页信息
        PageUtil pageUtil = new PageUtil(Math.toIntExact(page.getTotal()), pageNo, 10);
        List<Integer> pageNumList = pageUtil.countPreAndSufNo();


        model.addAttribute("blogs", page.getRecords())
                .addAttribute("pageNumList", pageNumList)
                .addAttribute("pageNo", pageNo)
                .addAttribute("totalPage", pageUtil.getTotalPageNo());

        getBlogRange(model);
        return "myCollect";
    }

    // 去到修改密码界面
    @GetMapping("/toModifyPassword")
    public String toModifyPassword() {
        return "modifyPassword";
    }

    //修改密码
    @PostMapping("/modifyPassword")
    public String modifyPassword(@RequestParam("newPassword") String password) {

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        UpdateWrapper<Users> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("user_password", password)
                .eq("id", userVO.getUser().id);

        boolean b = userService.update(updateWrapper);

        if (b) {

            return "redirect:/user/modifySuccess";
        } else {

            return "redirect:/user/modifyError";
        }

    }

    // 检测旧密码的正确
    @PostMapping("/checkPassword")
    @ResponseBody
    public Map<String, String> checkPassword(@RequestParam("userPassword") String password) {

        HashMap<String, String> map = new HashMap<>();

        // 获取本用户
        UserVO userVO = (UserVO) MyContextUtil.getSession().getAttribute("userVO");

        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.eq("id", userVO.getUser().id).select("user_password");
        Users one = userService.getOne(wrapper);

        if (!StringUtils.isEmpty(password) && one.userPassword.equals(password)) {

            map.put("msg", "right");
        } else {
            map.put("msg", "error");
        }
        return map;
    }

    // 修改密码成功页面
    @GetMapping("/modifySuccess")
    public String modifySuccess() {
        return "modifySuccess";
    }

    // 修改密码失败页面
    @GetMapping("/modifyError")
    public String modifyError(Model model) {

        model.addAttribute("msg", "修改密码失败");
        return "modifyPassword";
    }

    // 更新 likes数量
    public void updateLikes(Integer blogId) {
        QueryWrapper<Likes> likesQueryWrapper = new QueryWrapper<>();
        likesQueryWrapper.eq("blog_id", blogId);
        List<Likes> list = likeService.list(likesQueryWrapper);

        UpdateWrapper<Blogs> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("likes", list.size()).eq("id", blogId);
        blogService.update(updateWrapper);
    }


    // 计算排名方法
    public void getBlogRange(Model model) {

        QueryWrapper<Blogs> wrapper = new QueryWrapper<>();
        wrapper.select("id", "title", "likes").orderByDesc("likes");
        Page<Blogs> page = new Page<>(1, 5);

        blogService.page(page, wrapper);
        model.addAttribute("likeRange", page.getRecords());


        QueryWrapper<Blogs> wrapper1 = new QueryWrapper<>();
        wrapper1.select("id", "title", "views").orderByDesc("views");

        blogService.page(page, wrapper1);
        model.addAttribute("viewRange", page.getRecords());
    }
}
